<?php
// +----------------------------------------------------------------------
// | SwiftPHP [ JUST DO ONE THING WELL ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2017  http://swiftphp.zhongwenyu.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhongwenyu <zhongwenyu1987@163.com> <http://www.zhongwenyu.com>
// +----------------------------------------------------------------------
// | Times: 2017/2/16 16:12
// +----------------------------------------------------------------------
namespace swift;

class Url{
    protected static $domain;   // 是否显示域名
    protected static $bind;   // 域名绑定
    /**
     * URL生成 支持路由反射
     * @param string            $url 路由地址
     * @param string|array      $vars 参数（支持数组和字符串）a=val&b=val2... ['a'=>'val1', 'b'=>'val2']
     * @param string|bool       $suffix 伪静态后缀
     * @param boolean|string    $domain 是否显示域名 或者直接传入域名
     * @return string
     */
    public static function build($url = '', $vars = '', $suffix = null, $domain = true)
    {
        $depr = Config::get('pathinfo_depr');
        $request = Request::instance();
        $basefile = Config::get('url_rewrite') ? '/' : '/index.php/';

        if(is_null($suffix) && !empty(Config::get('url_html_suffix'))){
            $suffix = '.' . Config::get('url_html_suffix');
        }elseif(!empty($suffix)){
            $suffix = '.' . $suffix;
        }else{
            $suffix = '';
        }
        $info = parse_url($url);
        $url  = !empty($info['path']) ? $info['path'] : '';

        // 解析参数
        $query = [];
        if(is_string($vars) && !empty($vars)){
            parse_str($vars, $query);
        }else{
            $query = $vars;
        }
        isset($info['query']) && parse_str($info['query'], $query1);
        $query = isset($query1) ? array_merge($query , $query1) : $query;

        $rules = Route::rules(true);

        // 检测域名绑定
        $domains = $rules['domain'];
        self::parseDomain($url , $domains , $domain , $request);

        // 检测别名路由
        $alias = $rules['alias'];
        $matchAlias = false;
        if($alias){
            foreach($alias as $k => $v){
                if(is_array($v)){
                    $v = $v[0];
                }
                if(0 === strpos($url , $v)){
                    $url        = $k . substr($url, strlen($v));
                    $matchAlias = true;
                    break;
                }
            }
        }

        if(!$matchAlias){
            $matchRoute = implode('/' , array_slice(explode('/' , $url) , 0 , 3));

            // 检测普通路由
            $rule = $rules['name'][$matchRoute];
            if(!empty($rule)){
                $rule = $rules['name'][$matchRoute][0][0];
                if(strpos($rule , ':')){
                    $arr = [];
                    // 绑定路由参数
                    foreach(explode('/' , $rule) as $r){
                        if(strpos($r , ':') !== false){
                            if(strpos($r , '[') === 0){
                                $r = substr($r , 1 , -1);
                            }
                            $r = substr($r , 1);
                            if(isset($query[$r])){
                                $arr[] = $query[$r];
                                unset($query[$r]);
                            }
                        }else{
                            $arr[] = $r;
                        }
                    }
                    $rule = implode($depr , $arr);
                }
                $url = '/' . $rule . substr($url, strlen($matchRoute));
            }else{
                // 绑定域名路由
                !empty(self::$bind) && $url = substr($url, strlen(self::$bind));
            }
        }
        $url = trim($url , '/');
        // 绑定参数和伪静态后缀
        //!empty($query) && $url .= $depr . str_replace(['&' , '='] , $depr , http_build_query($query));
        $url .= $suffix;
        !empty($query) && $url .= '?' . http_build_query($query);

        // 组装url
        return self::$domain . $basefile . $url;
    }

    // 检测域名
    protected static function parseDomain($url, $domains , $domain , $request){
        $host = implode('.' , array_slice(explode('.' , $request->host()) , -2));
        $scheme = $request->scheme();

        foreach($domains as $k => $v){
            $v = $v['[bind]'][0];
            if(0 === strpos($url , $v)){
                if(false !== strpos($k , '*')){
                    if(empty($domain)){
                        throw new \Exception('必须设定子域名！');
                    }
                    $subdomain = $domain . substr($k , 1);
                } else {
                    $subdomain = $k;
                }
                self::$domain = $scheme . '://' . $subdomain . '.' . $host;
                self::$bind = $v;
            }
        }
    }
}

